home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <math.h>
- #include <malloc.h>
- #include <graph.h>
- #include <process.h>
- #include <stdlib.h>
- #include <conio.h>
-
- #define TRUE -1
- #define FALSE 0
-
- static double f(double,double);
- void main(void);
-
- void main()
- {
- static double aspect_ratio;
- static double box_delta_x;
- static double box_delta_y;
- static int box_num_1;
- static int box_num_2;
- static int box_x [4];
- static double box_x_intercept;
- static int box_x1;
- static int box_x2;
- static int box_y [4];
- static int box_y_max;
- static int box_y_min;
- static double box_y_offset;
- static int box_y1;
- static short color;
- static double cos_rotation;
- static double cos_tilt;
- static double delta_x;
- static double delta_y;
- static double delta_z;
- static int finished;
- static int intercept_count_mod_2;
- static int key_index_1;
- static int key_index_2;
- static int line_x1;
- static int line_x2;
- static int line_y1;
- static int line_y2;
- static double magnitude_normal;
- static int max_y_out;
- static int max_z_out;
- static double normal_x;
- static double normal_y;
- static double normal_z;
- static double num_bytes;
- static int num_x_divisions;
- static int num_x_primes;
- static int num_y_divisions;
- static double pixels_per_unit;
- static int prime_num;
- static double radians;
- static double radians_per_degree;
- static int response;
- static double rotation;
- static double sin_rotation;
- static double sin_tilt;
- static int sort_left;
- static int sort_right;
- static double sort_t1;
- static int sort_t2;
- static int sort_t3;
- static double tilt;
- static long tint;
- static long tint_increment;
- static double x;
- static int *x_division_index;
- static int x_division_num;
- static double x_eye;
- static double x_max;
- static double x_min;
- static double *x_prime;
- static double *x_prime_sorted;
- static double x_prime_max;
- static int x_prime_num;
- static double x_rotated;
- static double x0;
- static double x1;
- static double x2;
- static double x3;
- static double y;
- static double y_center;
- static int *y_division_index;
- static int y_division_num;
- static double y_max;
- static double y_min;
- static double y_offset;
- static double y_out_max;
- static double *y_prime;
- static double y_prime_max;
- static double y_prime_min;
- static double y0;
- static double y1;
- static double y2;
- static double y3;
- static double z;
- static double z_center;
- static double z_offset;
- static double z_out_max;
- static double *z_prime;
- static double z_prime_max;
- static double z_prime_min;
- static double z0;
- static double z1;
- static double z2;
- static double z3;
-
- max_y_out=319;
- max_z_out=199;
- printf(" Three Dimensional Plot\n\n\n\n");
- printf("Smallest value for x? "); fflush(stdout);
- scanf("%lf",&x_min);
- printf("Largest value for x? "); fflush(stdout);
- scanf("%lf",&x_max);
- printf("Smallest value for y? "); fflush(stdout);
- scanf("%lf",&y_min);
- printf("Largest value for y? "); fflush(stdout);
- scanf("%lf",&y_max);
- do
- {
- do
- {
- printf("Number of divisions for x? "); fflush(stdout);
- scanf("%d",&num_x_divisions);
- if (num_x_divisions <= 1)
- printf("? there must be at least 2 divisions\n");
- }
- while (num_x_divisions <= 1);
- do
- {
- printf("Number of divisions for y? "); fflush(stdout);
- scanf("%d",&num_y_divisions);
- if (num_y_divisions <= 1)
- printf("? there must be at least 2 divisions\n");
- }
- while (num_y_divisions <= 1);
- num_bytes=(float) num_x_divisions;
- num_bytes*=((float) num_y_divisions);
- num_bytes*=((float) sizeof(double));
- if (num_bytes > 65536.0)
- printf("? too many cells\n"); /* Oh, for a 32 bit compiler! */
- }
- while (num_bytes > 65536.0);
- if ((x_prime
- =(double *) malloc(num_x_divisions*num_y_divisions*sizeof(double)))
- == NULL)
- {
- printf("Fatal error: out of memory\n");
- exit(4);
- }
- if ((x_prime_sorted
- =(double *) malloc(num_x_divisions*num_y_divisions*sizeof(double)))
- == NULL)
- {
- printf("Fatal error: out of memory\n");
- exit(4);
- }
- if ((y_prime
- =(double *) malloc(num_x_divisions*num_y_divisions*sizeof(double)))
- == NULL)
- {
- printf("Fatal error: out of memory\n");
- exit(4);
- }
- if ((z_prime
- =(double *) malloc(num_x_divisions*num_y_divisions*sizeof(double)))
- == NULL)
- {
- printf("Fatal error: out of memory\n");
- exit(4);
- }
- if ((x_division_index
- =(int *) malloc(num_x_divisions*num_y_divisions*sizeof(int)))
- == NULL)
- {
- printf("Fatal error: out of memory\n");
- exit(4);
- }
- if ((y_division_index
- =(int *) malloc(num_x_divisions*num_y_divisions*sizeof(int)))
- == NULL)
- {
- printf("Fatal error: out of memory\n");
- exit(4);
- }
- do
- {
- printf("Rotation about the z-axis (degrees)? "); fflush(stdout);
- scanf("%lf",&rotation);
- printf("Tilt about the resulting y-axis (degrees)? "); fflush(stdout);
- scanf("%lf",&tilt);
- printf("After the plot is displayed, press a key to continue.\n");
- printf("Evaluating function...\n");
- radians_per_degree=atan(1.0)/45.0;
- radians=tilt*radians_per_degree;
- cos_tilt=cos(radians);
- sin_tilt=sin(radians);
- radians=rotation*radians_per_degree;
- cos_rotation=cos(radians);
- sin_rotation=sin(radians);
- z=f(x_min,y_min);
- x_rotated=x_min*cos_rotation+y_min*sin_rotation;
- y_prime_min=-x_min*sin_rotation+y_min*cos_rotation;
- z_prime_min=-x_rotated*sin_tilt+z*cos_tilt;
- y_prime_max=y_prime_min;
- z_prime_max=z_prime_min;
- x_prime_max=x_rotated*cos_tilt+z*sin_tilt;
- delta_x=(double) num_x_divisions;
- delta_x=(x_max-x_min)/delta_x;
- delta_y=(double) num_y_divisions;
- delta_y=(y_max-y_min)/delta_y;
- x=x_min;
- num_x_primes=0;
- for (x_division_num=0; x_division_num < num_x_divisions;
- x_division_num++)
- {
- y=y_min;
- for (y_division_num=0; y_division_num < num_y_divisions;
- y_division_num++)
- {
- z=f(x,y);
- x_division_index[num_x_primes]=x_division_num;
- y_division_index[num_x_primes]=y_division_num;
- x_rotated=x*cos_rotation+y*sin_rotation;
- y_prime[num_x_primes]=-x*sin_rotation+y*cos_rotation;
- x_prime[num_x_primes]=x_rotated*cos_tilt+z*sin_tilt;
- z_prime[num_x_primes]=-x_rotated*sin_tilt+z*cos_tilt;
- if (x_prime[num_x_primes] > x_prime_max)
- x_prime_max=x_prime[num_x_primes];
- if (y_prime[num_x_primes] < y_prime_min)
- y_prime_min=y_prime[num_x_primes];
- if (y_prime[num_x_primes] > y_prime_max)
- y_prime_max=y_prime[num_x_primes];
- if (z_prime[num_x_primes] < z_prime_min)
- z_prime_min=z_prime[num_x_primes];
- if (z_prime[num_x_primes] > z_prime_max)
- z_prime_max=z_prime[num_x_primes];
- y+=delta_y;
- num_x_primes++;
- }
- x+=delta_x;
- }
- printf("Adjusting perspective...\n");
- if ((y_prime_max-y_prime_min) > (z_prime_max-z_prime_min))
- x_eye=2.0*(y_prime_max-y_prime_min)+x_prime_max;
- else
- x_eye=2.0*(z_prime_max-z_prime_min)+x_prime_max;
- if (((y_prime_max-y_prime_min) > (z_prime_max-z_prime_min))
- || (z_prime_max != z_prime_min))
- {
- y_center=(y_prime_max+y_prime_min)/2.0;
- z_center=(z_prime_max+z_prime_min)/2.0;
- num_x_primes=0;
- for (x_division_num=0; x_division_num < num_x_divisions;
- x_division_num++)
- {
- y=y_min;
- for (y_division_num=0; y_division_num < num_y_divisions;
- y_division_num++)
- {
- x=x_prime[num_x_primes];
- y=y_prime[num_x_primes];
- z=z_prime[num_x_primes];
- delta_x=x-x_eye;
- delta_y=y-y_center;
- delta_z=z-z_center;
- x_prime[num_x_primes]
- =sqrt(delta_x*delta_x+delta_y*delta_y+delta_z*delta_z);
- y_prime[num_x_primes]
- =y_center+(y-y_center)*(x_eye-x_prime_max)/(x_eye-x);
- z_prime[num_x_primes]
- =z_center+(z-z_center)*(x_eye-x_prime_max)/(x_eye-x);
- num_x_primes++;
- }
- }
- }
- for (x_prime_num=0; x_prime_num < num_x_primes; x_prime_num++)
- x_prime_sorted[x_prime_num]=x_prime[x_prime_num];
- printf("Sorting points...\n");
- sort_left=num_x_primes/2;
- sort_right=num_x_primes-1;
- sort_t1=x_prime_sorted[0];
- sort_t2=x_division_index[0];
- sort_t3=y_division_index[0];
- while (sort_right > 0)
- {
- if (sort_left > 0)
- {
- sort_left--;
- sort_t1=x_prime_sorted[sort_left];
- sort_t2=x_division_index[sort_left];
- sort_t3=y_division_index[sort_left];
- }
- else
- {
- sort_t1=x_prime_sorted[sort_right];
- sort_t2=x_division_index[sort_right];
- sort_t3=y_division_index[sort_right];
- x_prime_sorted[sort_right]=x_prime_sorted[0];
- x_division_index[sort_right]=x_division_index[0];
- y_division_index[sort_right]=y_division_index[0];
- sort_right--;
- }
- if (sort_right > 0)
- {
- finished=FALSE;
- key_index_2=sort_left;
- while (! finished)
- {
- key_index_1=key_index_2;
- key_index_2=2*key_index_2+1;
- if (key_index_2 > sort_right)
- finished=TRUE;
- else
- {
- if (key_index_2 != sort_right)
- {
- if (x_prime_sorted[key_index_2]
- > x_prime_sorted[key_index_2+1])
- key_index_2++;
- }
- if (sort_t1 <= x_prime_sorted[key_index_2])
- finished=TRUE;
- else
- {
- x_prime_sorted[key_index_1]
- =x_prime_sorted[key_index_2];
- x_division_index[key_index_1]
- =x_division_index[key_index_2];
- y_division_index[key_index_1]
- =y_division_index[key_index_2];
- }
- }
- }
- x_prime_sorted[key_index_1]=sort_t1;
- x_division_index[key_index_1]=sort_t2;
- y_division_index[key_index_1]=sort_t3;
- }
- }
- x_prime_sorted[0]=sort_t1;
- x_division_index[0]=sort_t2;
- y_division_index[0]=sort_t3;
- _setvideomode(_MRES256COLOR);
- tint=0l;
- tint_increment=0x010101;
- for (color=0; color < 64; color++)
- {
- _remappalette(color,tint);
- tint+=tint_increment;
- }
- aspect_ratio=1.0/(4.0*(200.0/320.0)/3.0);
- y_out_max=(double) max_y_out;
- z_out_max=(double) max_z_out;
- if (aspect_ratio*z_out_max*(y_prime_max-y_prime_min)
- > y_out_max*(z_prime_max-z_prime_min))
- {
- pixels_per_unit=y_out_max/(aspect_ratio*(y_prime_max-y_prime_min));
- y_offset=0.0;
- z_offset=-(z_out_max-pixels_per_unit*(z_prime_max-z_prime_min))/2.0;
- }
- else
- if (aspect_ratio*z_out_max*(y_prime_max-y_prime_min)
- < y_out_max*(z_prime_max-z_prime_min))
- {
- pixels_per_unit=z_out_max/(z_prime_max-z_prime_min);
- y_offset=(y_out_max
- -aspect_ratio*pixels_per_unit*(y_prime_max-y_prime_min))/2.0;
- z_offset=0.0;
- }
- else
- {
- pixels_per_unit=1.0;
- y_offset=y_out_max/2.0;
- z_offset=-z_out_max/2.0;
- }
- for (x_prime_num=0; x_prime_num < num_x_primes; x_prime_num++)
- {
- x_division_num=x_division_index[x_prime_num];
- if (x_division_num < (num_x_divisions-1))
- {
- y_division_num=y_division_index[x_prime_num];
- if (y_division_num < (num_y_divisions-1))
- {
- prime_num=num_y_divisions*x_division_num+y_division_num;
- x0=x_prime[prime_num];
- y0=y_prime[prime_num];
- z0=z_prime[prime_num];
- prime_num+=num_y_divisions;
- x1=x_prime[prime_num];
- y1=y_prime[prime_num];
- z1=z_prime[prime_num];
- prime_num++;
- x2=x_prime[prime_num];
- y2=y_prime[prime_num];
- z2=z_prime[prime_num];
- prime_num-=num_y_divisions;
- x3=x_prime[prime_num];
- y3=y_prime[prime_num];
- z3=z_prime[prime_num];
- box_x[0]=(int) (y_offset
- +pixels_per_unit*aspect_ratio*(y0-y_prime_min));
- box_y[0]=(int) (z_offset+z_out_max
- -pixels_per_unit*(z0-z_prime_min));
- box_x[1]=(int) (y_offset
- +pixels_per_unit*aspect_ratio*(y1-y_prime_min));
- box_y[1]=(int) (z_offset+z_out_max
- -pixels_per_unit*(z1-z_prime_min));
- box_x[2]=(int) (y_offset
- +pixels_per_unit*aspect_ratio*(y2-y_prime_min));
- box_y[2]=(int) (z_offset+z_out_max
- -pixels_per_unit*(z2-z_prime_min));
- box_x[3]=(int) (y_offset
- +pixels_per_unit*aspect_ratio*(y3-y_prime_min));
- box_y[3]=(int) (z_offset+z_out_max
- -pixels_per_unit*(z3-z_prime_min));
- box_y_min=box_y[0];
- box_y_max=box_y_min;
- normal_x=(y1-y0)*(z3-z0)-(y3-y0)*(z1-z0);
- normal_y=(x3-x0)*(z1-z0)-(x1-x0)*(z3-z0);
- normal_z=(x1-x0)*(y3-y0)-(x3-x0)*(y1-y0);
- magnitude_normal=sqrt(
- normal_x*normal_x+normal_y*normal_y+normal_z*normal_z);
- if (magnitude_normal == 0.0)
- color=(short) 0;
- else
- {
- color=(short) (64.0*fabs(normal_x)/magnitude_normal);
- if (color == (short) 64)
- color=(short) 63;
- }
- for (box_num_1=1; box_num_1 < 4; box_num_1++)
- {
- if (box_y[box_num_1] < box_y_min)
- box_y_min=box_y[box_num_1];
- if (box_y[box_num_1] > box_y_max)
- box_y_max=box_y[box_num_1];
- }
- for (box_y1=box_y_min; box_y1 <= box_y_max; ++box_y1)
- {
- intercept_count_mod_2=0;
- box_num_2=1;
- for (box_num_1=0; box_num_1 < 4; ++box_num_1)
- {
- if (box_y[box_num_1] >= box_y1)
- {
- if (box_y1 > box_y[box_num_2])
- {
- box_delta_y=(double)
- (box_y[box_num_2]-box_y[box_num_1]);
- box_delta_x=(double)
- (box_x[box_num_2]-box_x[box_num_1]);
- box_y_offset=(double)
- (box_y1-box_y[box_num_1]);
- box_x_intercept=(double) (box_x[box_num_1]);
- box_x1=(int) ((box_delta_x*box_y_offset)
- /box_delta_y+box_x_intercept);
- if (intercept_count_mod_2 == 0)
- box_x2=box_x1;
- else
- {
- if (box_x1 < box_x2)
- {
- line_x1=box_x1;
- line_x2=box_x2;
- }
- else
- {
- line_x1=box_x2;
- line_x2=box_x1;
- }
- _setcolor(color);
- _setpixel(line_x1,box_y1);
- while (line_x1 < line_x2)
- {
- line_x1++;
- _setpixel(line_x1,box_y1);
- }
- }
- intercept_count_mod_2=1-intercept_count_mod_2;
- }
- }
- else
- {
- if (box_y1 <= box_y[box_num_2])
- {
- box_delta_y=(double)
- (box_y[box_num_2]-box_y[box_num_1]);
- box_delta_x=(double)
- (box_x[box_num_2]-box_x[box_num_1]);
- box_y_offset=(double)
- (box_y1-box_y[box_num_1]);
- box_x_intercept=(double) (box_x[box_num_1]);
- box_x1=(int) ((box_delta_x*box_y_offset)
- /box_delta_y+box_x_intercept);
- if (intercept_count_mod_2 == 0)
- box_x2=box_x1;
- else
- {
- if (box_x1 < box_x2)
- {
- line_x1=box_x1;
- line_x2=box_x2;
- }
- else
- {
- line_x1=box_x2;
- line_x2=box_x1;
- }
- _setcolor(color);
- _setpixel(line_x1,box_y1);
- while (line_x1 < line_x2)
- {
- line_x1++;
- _setpixel(line_x1,box_y1);
- }
- }
- intercept_count_mod_2=1-intercept_count_mod_2;
- }
- }
- box_num_2++;
- if (box_num_2 >= 4)
- box_num_2=0;
- }
- }
- box_num_2=1;
- for (box_num_1=0; box_num_1 < 4; ++box_num_1)
- {
- line_x1=box_x[box_num_1];
- line_y1=box_y[box_num_1];
- line_x2=box_x[box_num_2];
- line_y2=box_y[box_num_2];
- box_num_2++;
- _setcolor(color);
- _moveto(line_x1,line_y1);
- _lineto(line_x2,line_y2);
- if (box_num_2 >= 4)
- box_num_2=0;
- }
- }
- }
- }
- fflush(stdin);
- response=getch();
- fflush(stdin);
- _setvideomode(_DEFAULTMODE);
- printf(" Three Dimensional Plot\n\n\n\n");
- printf("Again (y or n)? ");
- response=getche();
- printf("\n");
- }
- while ((response == ((int) 'Y')) || (response == ((int) 'y')));
- free((void *) y_division_index);
- free((void *) x_division_index);
- free((void *) z_prime);
- free((void *) y_prime);
- free((void *) x_prime);
- }
-
- static double f(x,y)
- double x;
- double y;
- {
- static double t1;
- static double t2;
-
- t1=x*x+y*y;
- t2=cos(7.0*sqrt(t1));
- return(2*t2*t2/(1.0+30.0*t1));
- }
-